home *** CD-ROM | disk | FTP | other *** search
- /*
- * prototype joystick -- simple window with a joystick.
- * click right mouse button to activate joystick.
- * move mouse in direction to move drawing marker.
- * click left mouse button to draw fast.
- * click middle mouse button to draw slow.
- * click right to stop moving.
- * click right mouse twice (after stop moment) to return to normal state.
- *
- * The machine will not respond sometimes. I don't know why.
- * I need suggestions on fixing this interface and making it
- * more usable.
- *
- * compile -lsuntool -lsunwindow -lpixrect
- */
- #include <stdio.h>
- #include <suntool/sunview.h>
- #include <suntool/canvas.h>
- #include <sys/time.h>
- #include <ctype.h>
-
- #define when break;case
- #define otherwise break;default
- #define rrand random
- #define SCOREFILE "qix.scores"
-
- Frame frame;
- Canvas Draw, Joystick;
- Pixwin *draw_win, *joystick_win;
- Pixfont *big_font, *small_font;
-
- int
- /* routines to call on sigalrm or sigwinch */
- move_joystick(), move_pen(), redraw_board(),
- score, /* players score */
- lives, /* chances left before end of game */
- nitems; /* number of x/y coords in current line drawn */
-
- #define MAX_LIVES 5 /* each game gives 5 lives */
- #define LIVE 1
- #define DIE -1
-
- #define SPARK_TIME 500
-
- struct itimerval timeout;
-
- #define start_timer() \
- timeout.it_value.tv_usec = 50000, setitimer(ITIMER_REAL, &timeout, NULL);
- #define stop_timer() \
- timerclear(&timeout.it_value), setitimer(ITIMER_REAL, &timeout, NULL);
-
- #define LINE_SPACE 5 /* dist pen draws from other lines */
- #define MARKER_WIDTH 8
- #define TOP_BORDER 25
- #define BORDER 10 /* should be larger than MARKER_W */
-
- #define BOARD_WIDTH_IN_PIXELS 700
- #define BOARD_HEIGHT_IN_PIXELS 750
- #define BOARD_WIDTH ((BOARD_WIDTH_IN_PIXELS - 2 * BORDER)/LINE_SPACE)
- #define BOARD_HEIGHT ((BOARD_HEIGHT_IN_PIXELS-BORDER-TOP_BORDER)/LINE_SPACE)
- #define TOTAL_AREA ((BOARD_WIDTH-1) * (BOARD_HEIGHT-1))
- #define TOTAL_QUADRANTS (TOTAL_AREA * 4)
-
- #define MID_X BOARD_WIDTH_IN_PIXELS / 2
- #define MID_Y BOARD_HEIGHT_IN_PIXELS / 2
-
- /* the board is a two dimentional array of ints. Values of ints are masked */
- int board[BOARD_WIDTH][BOARD_HEIGHT];
-
- /*
- * each "cell" ("_CL_") in the playing board may have values masked in.
- * If a line is drawn thru a cell, it is entered from one direction and
- * is exited to another direction. It may be reentered thus setting the
- * bits again. When a region is "closed", it will be painted with a value
- * "_PNT_" -- initially, the left border of the board will contain cells whose
- * values will have left parts of the cells painted and right parts unpainted.
- */
- #define CL_LN_RT 0x0001
- #define CL_LN_LF 0x0002
- #define CL_LN_UP 0x0004
- #define CL_LN_DN 0x0008
- #define CL_PNT_UL 0x0010
- #define CL_PNT_UR 0x0020
- #define CL_PNT_LR 0x0040
- #define CL_PNT_LL 0x0080
-
- #define OLD_LINE 0x1000 /* line may be new, old, or neither */
- #define NEW_LINE 0x2000
-
- #define CL_PNT_TOP (CL_PNT_UL | CL_PNT_UR)
- #define CL_PNT_BOT (CL_PNT_LL | CL_PNT_LR)
- #define CL_PNT_LEFT (CL_PNT_UL | CL_PNT_LL)
- #define CL_PNT_RIGHT (CL_PNT_UR | CL_PNT_LR)
- #define PAINTED (CL_PNT_UL|CL_PNT_UR|CL_PNT_LL|CL_PNT_LR)
-
- #define check_painted(x, y, paint) ((board[x][y] & paint) == paint)
-
- #define SENS_FACTOR 3 /* mouse must move this many pixels to move joystick */
-
- #define convert_x(coord) ((coord) * LINE_SPACE + BORDER)
- #define convert_y(coord) ((coord) * LINE_SPACE + TOP_BORDER)
- #define pen_coord_x(coord) (convert_x(coord) - MARKER_WIDTH)
- #define pen_coord_y(coord) (convert_y(coord) - MARKER_WIDTH)
-
- extern Pixrect pen_image;
-
- /* place_pen() macro XOR's the pen at its current coordinates */
- #define place_pen() pw_rop(draw_win, \
- pen_coord_x(pen_x), pen_coord_y(pen_y), \
- 16, 16, XOR, &pen_image, 0, 0)
-
- #define XOR (PIX_SRC^PIX_DST)
- #define draw(x1,y1,x2,y2,OP) pw_vector(draw_win, x1,y1,x2,y2,(OP),1)
- #define box(x1,y1,x2,y2,OP) \
- draw(x1,y1,x1,y2,OP), draw(x1,y2,x2,y2,OP), \
- draw(x2,y2,x2,y1,OP), draw(x2,y1,x1,y1,OP)
-
- #ifdef DEBUG
- /* "Bert" is the little man who follows points in debug mode */
- #define show_bert(x, y) \
- if (debug > 2) \
- box(convert_x(x)-3, convert_y(y)-3, \
- convert_x(x)+3, convert_y(y)+3, XOR), \
- usleep(30000), \
- box(convert_x(x)-3, convert_y(y)-3, \
- convert_x(x)+3, convert_y(y)+3, XOR)
- #endif NOT_NOW
-
- #define l_width(font) (font)->pf_defaultsize.x
- #define l_height(font) (font)->pf_defaultsize.y
-
- int
- moving, /* if moving (e.g. !NO_MOVE), which direction */
- #define NO_MOVE 0
- #define STOP 1
- #define LEFT 2
- #define RIGHT 3
- #define UP 4
- #define DOWN 5
- #define LEFT_OF(d) (d==UP? LEFT : d==LEFT ? DOWN : d==DOWN ? RIGHT : UP)
- #define RIGHT_OF(d) (d==UP? RIGHT : d==RIGHT ? DOWN : d==DOWN ? LEFT : UP)
- #define OPP_OF(d) (d==UP? DOWN : d==RIGHT ? LEFT : d==DOWN ? UP : RIGHT)
-
- pen_x, pen_y, /* the coordinates of the drawing pen */
- fast, /* when we're drawing, are we drawing "fast"? */
- is_alive, /* if the current play is active or not */
- drawing, /* boolean: the pen is/not down (drawing) */
- level, /* completing 75% of the board raises you one level */
- Speed; /* aggressiveness/speed of qix */
- #define MAX_SPEED 15 /* I don't think speed'll ever reach this */
-
- struct region {
- int x, y;
- struct region *next, *prev;
- } *region, *cur_coord, *fuse;
-
- int saved_edge; /* Starting edge's original value of newly drawn lines */
- int area_closed;
- #ifdef DEBUG
- int debug, no_qix_kill; /* debugging stuff */
- #endif DEBUG
-
- int play_mode;
- #define REAL_PLAY -1 /* must be last in list */
- #define SHOW_SCORES 0
- #define SHOW_POINTS 1
- #define SHOW_QIX 2
- #define SHOW_SPARKS 3
- #define SHOW_FUSE 4
- #define SHOW_SPIRAL 5
- #define DEMO 6
-
- int time_left;
-